<?php
declare (strict_types=1);

namespace app\common\model;

class ProductCart extends Base
{
    protected function product(): object
    {
        return $this->hasOne(Product::class, 'id', 'pid')
            ->field('id,title,type_id,cate_1,cate_2,price,vip_price,icon,stock,sales,spec_open,status');
    }

    protected function getSpecValueAttr($val, $data): object|string
    {
        return $data['spec'] ? ProductSpec::where(['pid' => $data['pid'], 'merge_title' => $data['spec']])->find() : '';
    }

    public static function add($param, $user): array
    {
        try {
            if (!$param['num'] || $param['num'] <= 0) {
                throw new \Exception('数量有误');
            }
            $product = Product::where(['id' => $param['pid'], 'status' => 1])
                ->field('id,type_id,spec_open,stock')->find();
            if (empty($product)) {
                throw new \Exception('商品不存在或已下架');
            }
            if ($param['num'] > $product->stock) {
                throw new \Exception('库存不足');
            }
            $count = parent::where(['uid' => $user->id])->where('type_id', '<>', $product->type_id)->count();
            if ($count) {
                throw new \Exception('购物车已有其他专区商品，请先结算');
            }
            $map['type_id'] = $product->type_id;
            $map['uid'] = $user->id;
            $map['pid'] = $product->id;
            if ($product->spec_open == 2) {
                $specValue = ProductSpec::where(['pid' => $param['pid'], 'merge_title' => $param['spec']])->find();
                if (empty($specValue)) {
                    throw new \Exception('未查询到相关规格');
                }
                $map['spec'] = $param['spec'];
            }
            $cart = parent::where($map)->find();
            if ($cart) {
                $cart->num = $cart->num + $param['num'];
                $cart->save();
            } else {
                $map['num'] = $param['num'];
                parent::create($map);
            }

            return ['code' => 1, 'msg' => '加入成功'];
        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function edit($param, $user): array
    {
        try {
            $msg = '更新成功';
            switch ($param['type']) {
                case 1://加
                    $info = parent::where(['id' => $param['id']])->field('id,num,pid')->find();
                    if ($info->num > $info->product->stock) {
                        return ['code' => -1, 'msg' => '库存不足'];
                    }
                    $info->num = $info->num + 1;
                    $info->save();
                    break;
                case 2://减
                    $info = parent::where(['id' => $param['id']])->field('id,num')->find();
                    if ($info->num <= 1) {
                        return ['code' => -1, 'msg' => '数量至少为1'];
                    }
                    $info->num = $info->num - 1;
                    $info->save();
                    break;
                case 3://删
                    if (empty($param['cart_id'])) {
                        return ['code' => -1, 'msg' => '请选择要删除的商品'];
                    }
                    parent::destroy(['id' => array_values($param['cart_id'])], true);
                    $msg = '删除成功';
                    break;
                case 4://清空
                    parent::destroy(['uid' => $user->id], true);
                    $msg = '清空成功';
                    break;
                case 5://修改
                    $info = parent::where(['id' => $param['id']])->field('id,num,pid')->find();
                    if ($param['num'] > $info->product->stock) {
                        return ['code' => -1, 'msg' => '库存不足'];
                    }
                    $info->num = $param['num'];
                    $info->save();
                    break;
                default:
                    return ['code' => -1, 'msg' => '加载失败'];
            }

            return ['code' => 1, 'msg' => $msg];
        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function getSettled($id, $user): array
    {
        try {
            if (empty($id)) {
                throw new \Exception('请选择要结算的商品');
            }
            $type_id = $amountTotal = $freightTotal = 0;
            $productAll = [];
            $product = parent::with(['product'])->whereIn('id', $id)->where('uid', $user->id)
                ->append(['specValue'])->field('id,type_id,pid,num,spec')->select();
            if ($product->isEmpty()) {
                throw new \Exception('请选择要结算的商品');
            }
            foreach ($product as $item) {
                if ($item->product->status != 1) {
                    throw new \Exception('商品《' . $item->product->title . '》已下架');
                }
                if ($item->specValue) {
                    if ($item->num > $item->specValue->stock) {
                        throw new \Exception('商品《' . $item->product->title . '-' . $item->spec . '》库存不足');
                    }
                    $spec = $item->spec;
                    $icon = $item->specValue->icon ?: $item->product->icon;
                    $vip_price = $item->specValue->vip_price;
                } else {
                    if ($item->num > $item->product->stock) {
                        throw new \Exception('商品《' . $item->product->title . '》库存不足');
                    }
                    $spec = '';
                    $icon = $item->product->icon;
                    $vip_price = $item->product->vip_price;
                }
                $type_id = $item->product->type_id;
                $amount = round($vip_price * $item->num, 2);
                $freight = round($item->product->freight * $item->num, 2);
                $productAll[] = [
                    'pid' => $item->pid,
                    'type_id' => $item->product->type_id,
                    'title' => $item->product->title,
                    'spec' => $spec,
                    'icon' => $icon,
                    'num' => $item->num,
                    'vip_price' => $vip_price,
                    'amount' => $amount,
                    'freight' => $freight
                ];
                $amountTotal += $amount;
                $freightTotal += $freight;
            }
            $list = [
                'type_id' => $type_id,
                'product' => $productAll,
                'amount' => sprintf('%.2f', $amountTotal),
                'freight' => sprintf('%.2f', $freightTotal),
                'real_amount' => sprintf('%.2f', round($amountTotal + $freightTotal, 2))
            ];

            return ['code' => 1, 'msg' => 'success', 'data' => $list];
        } catch (\Exception $e) {

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }
}